.text
.global _start

_start:
    b reset
    ldr pc, und_addr
    ldr pc, swi_addr
    b halt
    b halt
    b halt
    ldr pc, irq_addr
    b halt 

und_addr:
    .word do_und

swi_addr:
    .word do_swi

irq_addr:
    .word do_irq

.align 4
do_und:
    /* 保护现场 */
    ldr sp, =0x34000000
    stmdb sp!, {r0-r12, lr}

    /* 处理异常 */
    mrs r0, cpsr
    ldr r1, =und_string
    bl printException

    /* 恢复现场 */
    ldmia sp!, {r0-r12, pc}^ /* ^会把spsr的值恢复到cpsr里 */

und_string:
    .string "undefined instruction exception"

.align 4
do_swi:
    /* 保护现场 */
    ldr sp, =0x33e00000
    stmdb sp!, {r0-r12, lr}

    mov r4, lr

    /* 处理异常 */
    mrs r0, cpsr
    ldr r1, =swi_string
    bl printException

    sub r0, r4, #4
    bl printSWIVal

    /* 恢复现场 */
    ldmia sp!, {r0-r12, pc}^ /* ^会把spsr的值恢复到cpsr里 */

swi_string:
    .string "swi exception"

.align 4
do_irq:
    /* 保护现场 */
    ldr sp, =0x33d00000

    sub lr, lr, #4
    stmdb sp!, {r0-r12, lr}

    /* 处理异常 */
    bl handle_irq

    /* 恢复现场 */
    ldmia sp!, {r0-r12, pc}^ /* ^会把spsr的值恢复到cpsr里 */

.align 4

reset:
    /* 关看门狗 */
    ldr r0, =0x53000000
    ldr r1, =0
    str r1, [r0]

    /*设置MPLL, FCLK:HCLK:PCLK = 400MHz: 100MHz: 50MHz */
    ldr r0, =0x4C000000
    ldr r1, =0xFFFFFFFF
    str r1, [r0]

    ldr r0, =0x4C000014
    ldr r1, = 0x5
    str r1, [r0]

    mrc p15,0,r0,c1,c0,0
    orr r0,r0,#0xC0000000
    mcr p15,0,r0,c1,c0,0

    ldr r0, =0x4C000004
    ldr r1, = (92<<12)|(1<<4)|(1<<0)
    str r1, [r0]

    /* 判断nor还是nand启动 */
    mov r1, #0
    ldr r0, [r1]
    str r1, [r1]
    ldr r2, [r1]
    cmp r1, r2
    ldr sp, =0x40000000+4096 /*nor 启动 */
    moveq sp, #4096 /*nand启动 */
    streq r0, [r1]

    bl sdram_init

    /* 重定位text, rodata, data段整个程序 */
	bl copy2sdram

	/* 清除BSS段 */
	bl clean_bss

    /* 切换到usr模式 */
    mrs r0, cpsr
    bic r0, r0, #0xf
    bic r0, r0, #(1<<7)  /*  清除I位 */
    msr cpsr, r0

    /* 设置 usr sp */
    ldr sp, =0x33f00000

    ldr pc, =sdram

sdram:
    bl uart0_init
    bl print1

    /*故意加入一条未定义指令 */
und_code:
    .word 0xdeadc0de

    swi 0x123

    @ bl main
    ldr lr, =halt
    ldr pc, =main

halt:
    b halt
